package com.kania.simpleemail.mailview;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeUtility;

import android.app.Activity;
import android.app.Fragment;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.kania.simpleemail.R;
import com.kania.simpleemail.core.IMAP;
import com.kania.simpleemail.data.MailData;
import com.kania.simpleemail.mailview.DetailViewFragment.ButtonIncludeAttachment.FileDownloadTask;
import com.sun.mail.imap.IMAPFolder;

public class DetailViewFragment extends Fragment implements View.OnClickListener {
	private static MailData maildata;
	private static Folder folder;
	private static Message message;
	
	//test
	private LinearLayout layoutInfo;
	
	private TextView textFrom;
	private TextView textTo;
	private TextView textCC;
	private TextView textBCC;
	private TextView textSubject;
	private TextView textDate;
	private WebView webContent; 
	
	private String sTag = "KANIA_TAG_DETAILVIEW";
	
	private String sPath = "/sdcard/SimpleEmail/";
	
	private OneMailReadTask taskOneMailRead;
	private FileDownloadTask taskFileDownload;
	
	private String sID;
	private String sPassword;
	private String sHost;
	
	private View layoutView;
	
	private ArrayList<ButtonIncludeAttachment> alBtnAttach = new ArrayList<DetailViewFragment.ButtonIncludeAttachment>();
	
	public static final int MSG_SETINFO = 0;
	public static final int MSG_START_DOWN_NOTI = 1;
	public static final int MSG_COMPLETE_DOWN_NOTI = 2;
//	public static final int MSG_INCOMPLETE_DOWN_NOTI = 3;
	
	public static final int NOTI_START_DOWN_NOTI = 1;
	public static final int NOTI_COMPLETE_DOWN_NOTI = 2;
//	public final int NOTI_INCOMPLETE_DOWN_NOTI = 3;
	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(android.os.Message msg) {
			Bundle data = msg.getData();
			switch (data.getInt("msgtype")) {
			case MSG_SETINFO:
				textFrom.setText(maildata.getFromData());
				textTo.setText(maildata.getToData());
				textCC.setText(maildata.getCCData());
				textBCC.setText(maildata.getBCCData());
				textSubject.setText(maildata.getMailSubject());
				textDate.setText(maildata.getMailDate());
				webContent.loadData(maildata.getContents(), "text/html", null);
				
				for(ButtonIncludeAttachment btn: alBtnAttach) {
					layoutInfo.addView(btn);
				}
				break;
			case MSG_START_DOWN_NOTI:
			{
				Activity activity = getActivity();
				Notification.Builder notiBuilder = new Notification.Builder(activity.getApplicationContext());
				notiBuilder.setSmallIcon(R.drawable.ic_launcher);
				notiBuilder.setContentTitle("SimpleEmail : Downloading...");
				notiBuilder.setContentText("Download progressing : " + data.getString("filename"));
				Notification noti = notiBuilder.build();

				NotificationManager notiManager = (NotificationManager)activity.getSystemService(activity.NOTIFICATION_SERVICE);
				notiManager.notify(NOTI_START_DOWN_NOTI, noti);
			}

			break;
			case MSG_COMPLETE_DOWN_NOTI:
			{
				Activity activity = getActivity();
				Notification.Builder notiBuilder = new Notification.Builder(activity.getApplicationContext());
				notiBuilder.setSmallIcon(R.drawable.ic_launcher);
				notiBuilder.setContentTitle("SimpleEmail : Download");
				notiBuilder.setContentText("Download Complete : " + data.getString("filename"));
				Notification noti = notiBuilder.build();

				NotificationManager notiManager = (NotificationManager)activity.getSystemService(activity.NOTIFICATION_SERVICE);
				notiManager.cancel(NOTI_START_DOWN_NOTI);
				notiManager.notify(NOTI_COMPLETE_DOWN_NOTI, noti);
			}
			break;
			}

		}
	};
	
	public DetailViewFragment() {}
	
	//r11 이후로 사용되지 않음
	public DetailViewFragment(Folder _folder, MailData _maildata) {
		folder = _folder;
		maildata = _maildata;
		Log.d(sTag, "Mail Received = " + maildata.getUID() + " : ");
		Log.d(sTag, "\tUID :" + maildata.getUID());
		Log.d(sTag, "\tFrom :" + maildata.getFromData());
		Log.d(sTag, "\tTo :" + maildata.getToData());
		Log.d(sTag, "\tCC :" + maildata.getCCData());
		Log.d(sTag, "\tBCC :" + maildata.getBCCData());
		Log.d(sTag, "\tData :" + maildata.getMailDate());
		Log.d(sTag, "\tSubject :" + maildata.getMailSubject());
	}
	
	public DetailViewFragment (MailData _maildata, String _ID, String _password, String _host) {
		maildata = _maildata;
		sID = _ID;
		sPassword = _password;
		sHost = _host;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View ConvertView = inflater.inflate(R.layout.fragment_detail_view, container, false); 
		layoutView = ConvertView;
		
		textFrom = (TextView)ConvertView.findViewById(R.id.detailviewFragTextFrom);
		textTo = (TextView)ConvertView.findViewById(R.id.detailviewFragTextTo);
		textCC = (TextView)ConvertView.findViewById(R.id.detailviewFragTextCC);
		textBCC = (TextView)ConvertView.findViewById(R.id.detailviewFragTextBCC);
		textSubject = (TextView)ConvertView.findViewById(R.id.detailviewFragTextSubject);
		textDate = (TextView)ConvertView.findViewById(R.id.detailviewFragTextDate);
		webContent = (WebView)ConvertView.findViewById(R.id.detailviewFragWebViewContents);
		webContent.loadData("Loading...", "text/plain", null);
		
		textFrom.setOnClickListener(this);
		textTo.setOnClickListener(this);
		textCC.setOnClickListener(this);
		textBCC.setOnClickListener(this);
		textSubject.setOnClickListener(this);
		textDate.setOnClickListener(this);
		
		taskOneMailRead = new OneMailReadTask();
		taskOneMailRead.execute();
		
		return ConvertView;
	}
	
	public void parseContent(Part msg, MailData md) throws IOException, MessagingException{
		//TODO [130816] 이 부분은 재귀적으로 메일 내용을 읽어 와야함. 추후 구현 예정
		boolean haveAttach = false;
		if(msg.isMimeType("multipart/*")) {
			
			Multipart multipart = (Multipart)msg.getContent();
			for(int partIndex = 0; partIndex < multipart.getCount(); partIndex++) {
				Part part = multipart.getBodyPart(partIndex);

				parseContent(part, md);
			}
		} else if (msg.isMimeType("text/plain")) {
			
			String str = MimeUtility.decodeText(msg.getContent().toString());
			Log.d(sTag, "text/plain case convert before : " + str);
//			md.setContents(new String(str.getBytes("EUC-KR"), "UTF-8"));
			md.setContents(str);
			Log.d(sTag, "text/plain case convert after : " + md.getContents());
			//TODO
		} else if (msg.isMimeType("text/html")) {
			String str = MimeUtility.decodeText(msg.getContent().toString());
			Log.d(sTag, "text/html case convert before : " + str);
//			md.setContents(new String(str.getBytes("EUC-KR"), "UTF-8"));
			md.setContents(str);
			Log.d(sTag, "text/html case convert after : " + md.getContents());
			//TODO
		} else {
			haveAttach = true;
//			md.setContents(md.getContents() + "[ATTACHMENT]");
		}
		
		if(haveAttach) {
			String disposiotion = msg.getDisposition();
			
			if(disposiotion == null || Part.ATTACHMENT.equalsIgnoreCase(disposiotion)) {
				String filename = msg.getFileName();
				ButtonIncludeAttachment btnAttach = new ButtonIncludeAttachment(getActivity(), filename, msg);
				alBtnAttach.add(btnAttach);
			}
		}
	}
	
	@Override
	public void onResume() {
		//test
		
		
		
		super.onResume();
		
		
	}
	
	@Override
	public void onPause() {
		super.onPause();
	}
	
	@Override
	public void onClick(View view) {
		// TODO from이나 to등의 infomation을 눌렀을 때의 singleline 설정을 바꾸도록 한다.
		switch (view.getId()) {
		case R.id.detailviewFragTextFrom:
		case R.id.detailviewFragTextTo:
		case R.id.detailviewFragTextCC:
		case R.id.detailviewFragTextBCC:
		case R.id.detailviewFragTextSubject:
		case R.id.detailviewFragTextDate:
			((TextView)view).setSingleLine(false); //이부분 좀 심플하고 간결하게 다시 원복 할 수 있는 방법이 있으면 좀 ㅜㅜ
			break;
		}
		
	}
	
	class ButtonIncludeAttachment extends Button{
		Part part;
		String filename;
		
		public ButtonIncludeAttachment(Context context, String _filename, Part _part) throws MessagingException {
			super(context);
			Log.d(sTag, "Click attachment button");
			filename = _filename;
			part = _part;
			this.setText(filename);
			this.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 10);
			LinearLayout.LayoutParams btnParam = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
			btnParam.setMargins(10, 10, 10, 10);
			this.setLayoutParams(btnParam);
			this.setBackgroundResource(R.drawable.attach_box);
			this.setPadding(10,  10, 10, 10);
			this.setClickable(true);
			this.setOnClickListener(new Button.OnClickListener() {
				@Override
				public void onClick(View v) {
					String filename = ((TextView)v).getText().toString();
					android.os.Message msg = android.os.Message.obtain();
					Bundle data = new Bundle();
					data.putInt("msgtype", MSG_START_DOWN_NOTI);
					data.putString("filename", filename);
					msg.setData(data);
					mHandler.sendMessage(msg);
					taskFileDownload = new FileDownloadTask();
					taskFileDownload.execute();
				}
			});
		}
		
		class FileDownloadTask extends AsyncTask<Void, Void, Boolean> {
			@Override
			protected Boolean doInBackground(Void... params) {
				try {
					File dir = new File(sPath);
					if (!dir.exists()) {
						dir.mkdirs();
					}
//					File file = new File(sPath + filename);
//					if (file.exists()) {
//						int fileCount = 1;
//						do {
//							File newfile = new File(sPath + filename + "(" + fileCount + ")");
//							if (file.exists()) {
//								fileCount++;
//								continue;
//							} else {
//								file = newfile;
//								break;
//							}
//						} while (true);
////						throw new IOException("file already exist");
//					}
					String checkFilename = filename;
					Log.d(sTag, "checkFilename : " + checkFilename);
					do {
						int duplicateFileCount = 0;
						File checkFile = new File(sPath + checkFilename);
						if (checkFile.exists()){
							Log.d(sTag, checkFilename + " is aleady exist");
							duplicateFileCount++;
							String splitFilename[] = checkFilename.split("\\.");
							Log.d(sTag, "splitFilename.length : " + splitFilename.length);
							checkFilename = "";
							for(int i = 0; i < (splitFilename.length-1); i++) {
								checkFilename += splitFilename[i];
							}
							//TODO 이부분은 그냥 정신놓고 하다보니 웃기게 된 부분. 추후 고칩시다 꼭 ㅋㅋ
							checkFilename += ("(" + duplicateFileCount + ")." + splitFilename[splitFilename.length-1]);
							Log.d(sTag, " filename changed : " + checkFilename);
						} else {
							break;
						}
					} while (true);
					File file = new File(sPath + checkFilename);
					FileOutputStream fos = new FileOutputStream(file);
					InputStream is = ((MimeBodyPart)part).getInputStream();
					int c;
					while ((c = is.read()) != -1) {
						fos.write(c);
					}
					
				} catch(IOException e) {
					Log.d(sTag, "IOException in saving attach");
					e.printStackTrace();
				} catch (MessagingException e) {
					Log.d(sTag, "MessagingException in saving attach");
					e.printStackTrace();
				}
				return null;
			}
			@Override
			protected void onPostExecute(Boolean result) {
				// 완료 noti를 띄운다
				android.os.Message msg = android.os.Message.obtain();
				Bundle data = new Bundle();
				data.putInt("msgtype", MSG_COMPLETE_DOWN_NOTI);
				data.putString("filename", filename);
				msg.setData(data);
				mHandler.sendMessage(msg);
				super.onPostExecute(result);
			}
		}
	}
	
	class OneMailReadTask extends AsyncTask<Void, Void, Boolean> {

		@Override
		protected Boolean doInBackground(Void... params) {
			IMAP MailReadSession;
			layoutInfo = (LinearLayout)layoutView.findViewById(R.id.detailviewFragLayoutInfo);
			
//			ArrayList<String> alAttach = maildata.getAttachArrayList();
			
			try {
				MailReadSession = IMAP.getInstance();
//				loginSession.initIMAP(sHost, sID, sPassword);
//				loginSession.open();
				folder = MailReadSession.getFolder();

//				Log.d("KANIA_TEST", "folder = " + folder + " , UID = " + maildata.getUID());
				message = ((IMAPFolder)folder).getMessageByUID(maildata.getUID());
				parseContent(message, maildata);
			} catch (IOException e) {
				Log.e(sTag, "IOException in message parsing");
				e.printStackTrace();
			} catch (MessagingException e) {
				Log.e(sTag, "MessagingException in message parsing");
				e.printStackTrace();
			}
			
//			mHandler.sendEmptyMessage(0);
			android.os.Message msg = android.os.Message.obtain();
			Bundle data = new Bundle();
			data.putInt("msgtype", MSG_SETINFO);
			msg.setData(data);
			mHandler.sendMessage(msg);
			return null;
		} 
		
		
	}
	
	
}
